package com.xls.commonlibrary.http;

import static com.xls.commonlibrary.constant.Const.DEVICE_OAID;

import android.text.TextUtils;
import android.util.Log;

import com.hjq.gson.factory.GsonFactory;
import com.xls.commonlibrary.BuildConfig;
import com.xls.commonlibrary.app.MainApplication;
import com.xls.commonlibrary.http.box.SPUtils;
import com.xls.commonlibrary.http.gson.CustomGsonConverterFactory;
//import com.xls.commonlibrary.risk.RiskUtil;
import com.xls.commonlibrary.util.MMKVUtil;
import com.xls.commonlibrary.util.NetUtil;
import com.xls.commonlibrary.util.SysDataUtil;
import com.xls.commonlibrary.util.TokenUtil;

import java.io.IOException;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitHelper {

    private static volatile RetrofitHelper singleton = null;
    Retrofit retrofit;
    private String TAG = "RetrofitHelper";

    private RetrofitHelper() {
        initRetrofit();
    }

    public static RetrofitHelper getInstance() {
        if (singleton == null) {
            synchronized (RetrofitHelper.class) {
                if (singleton == null) {
                    singleton = new RetrofitHelper();
                }
            }
        }
        return singleton;
    }

    /**
     * 创建API
     */
    public <T> T create(Class<T> clazz) {
        return retrofit.create(clazz);
    }

    public void initRetrofit() {
        // 底层具体请求的实现交给okhttp（虽然retrofit底层就是用的okhttp，但是这里单独配置，可以便于我们自定义拦截器。关于拦截器，这里不作深入探讨）
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        // add 拦截器  log   etc   超时 retry等 todo
        builder.addInterceptor(getHttpLoggingInterceptor());
//        builder.addInterceptor(getHeaderInterceptor());// ???
        builder.addNetworkInterceptor(getHeaderInterceptor());

        // 创建一个retrofit
        retrofit = new Retrofit.Builder()
                .client(builder.build())
                // 设置基址
//                .baseUrl("http://192.168.66.189") // pc 子浩
//                .baseUrl("http://192.168.66.252")// 文志本地

//                .baseUrl("http://ad.xinliansheng.top")// 外网 域名 【正式】
                .baseUrl(BuildConfig.BASE_COM_URL_HTTP)// 外网 域名 【测试】

                // 适配rxjava，目的在于使用观察者模式，分解上层请求的过程，便于我们横加干预（比如请求嵌套）
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(GsonFactory.getSingletonGson()))// Gson格式容错ilb
//                .addConverterFactory(CustomGsonConverterFactory.create())// Gson自定义解析json，并处理token等异常信息
                // 使用Gson框架解析请求返回的结果，因为返回的是xml，只有解析过后，才能将数据变为对象，放置到我们刚刚创建你的实体类当中，便于数据的传递使用
//                .addConverterFactory(GsonConverterFactory.create())
                // todo 自定义Gson解析,处理token失效，版本失效 自定义Exception 传到 onError()
                .build();

        // use 创建一个request
        //Request request = retrofit.create(Request.class);


    }

    /**
     * 日志输出
     * 自行判定是否添加
     *
     * @return
     */
    private HttpLoggingInterceptor getHttpLoggingInterceptor() {
        //日志显示级别
        HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY;
        //新建log拦截器
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                // debug 才输出
                if (!BuildConfig.LOGGABLE) return;
                Log.d(TAG, "Retrofit====Message:" + message);
            }
        });
        loggingInterceptor.setLevel(level);
        return loggingInterceptor;
    }

    private Interceptor getHeaderInterceptor() {
        // header add token
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
//                // 注意：不能调，调了到此结束
//                // request.body().
//
//                        .header("Authorization", TokenUtil.getInstance().getToken())
////                        .header("token", TokenUtil.getInstance().getToken())
////                        .header("Accept", "application/json")
//                        .method(original.method(), original.body());
//
//                Request request = requestBuilder.build();
//                return chain.proceed(request);


                String oaid = MMKVUtil.getInstance().getKV().decodeString(DEVICE_OAID, "");
                String token = TokenUtil.getInstance().getToken();
//                String tokenLianshanRisk = RiskUtil.getInstance().getToken();
                String packageName = SysDataUtil.getInstance().getPkName();


                Request original = chain.request();
                Request.Builder requestBuilder = original.newBuilder()
                        // game's
//                        .addHeader("deviceId", oaid)
//                        .addHeader("tokenLianshanRisk", tokenLianshanRisk)
//                        .addHeader("ipv4", NetUtil.getIPV4())
                        // box's
//                        .addHeader("token", SPUtils.getLoginToken(MainApplication.getAppContext()))
                        .addHeader("User-Type", "app");

                if (!TextUtils.isEmpty(packageName)) {
                    requestBuilder.addHeader("packageName", packageName);
                }
                if (!TextUtils.isEmpty(token)) {
                    requestBuilder.addHeader("authorization", token);
                }
                if (!TextUtils.isEmpty(oaid)) {
                    requestBuilder.addHeader("deviceId", oaid);
                }
//                if (!TextUtils.isEmpty(tokenLianshanRisk)) {
//                    requestBuilder.addHeader("tokenLianshanRisk", tokenLianshanRisk);
//                }
                if (!TextUtils.isEmpty(NetUtil.getIPV4())) {
                    requestBuilder.addHeader("ipv4", NetUtil.getIPV4());
                }
                if (!TextUtils.isEmpty(SPUtils.getLoginToken(MainApplication.getAppContext()))) {
                    requestBuilder.addHeader("token", SPUtils.getLoginToken(MainApplication.getAppContext()));
                }
                if (!TextUtils.isEmpty(BuildConfig.APPID)) {
                    requestBuilder.addHeader("appId", BuildConfig.APPID);
                }

                Request updateRequest = requestBuilder.build();
                return chain.proceed(updateRequest);


            }
        };
    }


}
